﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;
using UnityEngine;

[DisallowMultipleComponent]
public class OutLog : MonoBehaviour
{
    private struct LogLine
    {
        public string contex;
        public GUIStyle style;
    }

    static List<LogLine> mLines = new List<LogLine>();
    static List<string> mWriteTxt = new List<string>();
    static List<string> mCrashInfo = new List<string>();
    const long MAXFILE_SIZE = 1000 * GlobalNum.FILE_SIZE;

    private static string outpath;
    private static GUIStyle style;
    private static GUIStyle msgStyle;

    void Start()
    {
        //Application.persistentDataPath Unity中只有这个路径是既可以读也可以写的。
        outpath = Application.persistentDataPath + "/outLog.txt";
        //每次启动客户端删除之前保存的Log
        if (File.Exists(outpath))
        {
            if ((new FileInfo(outpath)).Length >= MAXFILE_SIZE)
            {
                File.Delete(outpath);
            }
        }

        style = new GUIStyle();
        style.normal.textColor = Color.red;
        style.fontSize = 20;
        msgStyle = new GUIStyle();
        msgStyle.normal.textColor = Color.green;
        msgStyle.fontSize = 13;

        //在这里做一个Log的监听
        //Application.logMessageReceived += HandleLog;
        //崩溃监听
        Application.logMessageReceived += HandleCrash;
        EDebug.Log("\n\n----" + DateTime.Now.ToString() + "----\n\n");
    }

    void Update()
    {
        //因为写入文件的操作必须在主线程中完成，所以在Update中哦给你写入文件。
        if (mWriteTxt.Count > 0)
        {
            string[] temp = mWriteTxt.ToArray();
            foreach (string t in temp)
            {
                using (StreamWriter writer = new StreamWriter(outpath, true, Encoding.UTF8))
                {
                    writer.WriteLine(t);
                }
                mWriteTxt.Remove(t);
            }
        }
    }

    void OnGUI()
    {
        for (int i = 0, imax = mLines.Count; i < imax; ++i)
        {
            GUILayout.Label(mLines[i].contex, mLines[i].style);
        }
    }

    public static void HandleLog(string logString, string stackTrace, LogType type)
    {
        mWriteTxt.Add(logString);
        if (type == LogType.Error || type == LogType.Exception)
        {
            mWriteTxt.Add(stackTrace);
            Log(style, logString);
            Log(style, stackTrace);
            Log(style, "log path:" + outpath);
            //SendMail(logString + stackTrace);
        }
        //HandleCrash(logString, stackTrace, type);
    }
    
    public static void HandleCrash(string logString, string stackTrace, LogType type)
    {
        if (LogType.Error != type && LogType.Exception != type) { return; }
        if (mCrashInfo.Contains(logString)) { return; }

        mCrashInfo.Add(logString);
#if DEBUG
        HandleLog(logString, stackTrace, type);
#endif
    }

    //这里我把错误的信息保存起来，用来输出在手机屏幕上
    public static void Log(GUIStyle pstyle, params object[] objs)
    {
        string text = "";
        for (int i = 0; i < objs.Length; ++i)
        {
            if (i == 0)
            {
                text += objs[i].ToString();
            }
            else
            {
                text += ", " + objs[i].ToString();
            }
        }

        if (Application.isPlaying)
        {
            if (mLines.Count > 15)
            {
                mLines.RemoveAt(0);
            }
            LogLine line = new LogLine();
            line.contex = text;
            line.style = pstyle;
            mLines.Add(line);
        }
    }
    
    public static void SendMail(string body)
    {
        //构造一个发件人地址对象
        MailAddress from = new MailAddress("wang10998588@126.com", "王艳斌", Encoding.UTF8);
        //构造一个收件人地址对象
        MailAddress to = new MailAddress("278696311@qq.com", "bug管理员", Encoding.UTF8);
       
        //构造一个Email的Message对象
        MailMessage message = new MailMessage(from, to);
        //添加邮件主题和内容
        message.Subject = "客户端报错";
        message.SubjectEncoding = Encoding.UTF8;
        message.BodyEncoding = Encoding.UTF8;
        message.Body = body;
        message.IsBodyHtml = false;

        //确定smtp服务器地址。实例化一个Smtp客户端
        SmtpClient client = new SmtpClient("smtp.126.com");
        //设置邮件的信息
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.EnableSsl = false;
        //设置用户名和密码
        client.UseDefaultCredentials = false;
        //用户登陆信息
        NetworkCredential myCredentials = new NetworkCredential("wang10998588", "baby51771");
        client.Credentials = (ICredentialsByHost)myCredentials;
        //发送邮件
        client.Send(message);
    }
}